<!--
 * @Author       : wfl
 * @LastEditors  : wfl
 * @description  :
 * @updateInfo   :
 * @Date         : 2023-05-25 18:33:20
 * @LastEditTime : 2023-06-05 09:57:04
-->
<script setup lang="ts" name="IkUploadPhoto">
import { onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { UploadFile } from 'element-plus'

const uploadUrl = '/api/upload'

const BUTTON_TEXT_DEFAULT = '点击上传图片'
const BUTTON_TEXT_UPLOADING = '正在上传...'
const ERROR_TEXT_DEFAULT = '上传失败，请重试'

const status = ref('idle')
const progress = ref(0)
const buttonText = ref(BUTTON_TEXT_DEFAULT)
const errorText = ref(ERROR_TEXT_DEFAULT)

const isUploading = ref(false)

const cacheFiles: Ref<Array<File> | null> = ref(null)

const handleChange = async (event: UploadFile) => {
  const file = event.raw
  if (!file)
    return
  cacheFiles.value?.push(file)
  isUploading.value = true
  status.value = 'uploading'
  buttonText.value = BUTTON_TEXT_UPLOADING

  const formData = new FormData()
  formData.append('file', file)

  try {
    const response = await fetch(uploadUrl, {
      method: 'POST',
      body: formData
    })
    const result = await response.json()

    if (response.status === 200 && result.success) {
      status.value = 'success'
    }
    else {
      status.value = 'error'
      errorText.value = result.message || ERROR_TEXT_DEFAULT
    }
  }
  catch (error) {
    status.value = 'error'
    errorText.value = ERROR_TEXT_DEFAULT
  }

  isUploading.value = false
}

const uploadRef = ref()
const retry = () => {
  status.value = 'idle'
  errorText.value = ERROR_TEXT_DEFAULT;
  (uploadRef.value as any).clearFiles()
}

const progressText = computed(() => `${progress.value.toFixed(2)}%`)

onMounted(() => {
  ElMessage({
    message: '请上传一张图片并等待上传结果',
    type: 'info'
  })
})
</script>

<template>
  <div>
    <el-upload
      ref="uploadRef"
      :action="uploadUrl"
      :show-file-list="false"
      :on-change="handleChange"
      :disabled="isUploading"
    >
      <template #default>
        <div class="upload-container">
          <div v-if="status === 'idle'" class="upload-content">
            <i class="el-icon-plus upload-icon"></i>
            <div class="upload-text">{{ buttonText }}</div>
          </div>
          <div v-else class="upload-content">
            <div v-if="status === 'uploading'" class="upload-progress">
              <el-progress :percentage="progress" status="exception" />
              <div class="upload-text">{{ progressText }}</div>
            </div>
            <div v-else-if="status === 'error'" class="upload-error">
              <i class="el-icon-close upload-icon"></i>
              <div class="upload-text">{{ errorText }}</div>
              <a href="#" @click.prevent="retry">重新上传</a>
            </div>
            <div v-else class="upload-success">
              <i class="el-icon-check upload-icon"></i>
              <div class="upload-text">上传成功</div>
            </div>
          </div>
        </div>
      </template>
    </el-upload>
  </div>
</template>

<style scoped>
.upload-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}

.upload-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 200px;
  height: 200px;
  border: 1px dashed #ccc;
  border-radius: 4px;
  cursor: pointer;
}

.upload-progress {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.upload-icon {
  font-size: 48px;
  color: #999;
}

.upload-text {
  margin-top: 10px;
}

.upload-error {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #f56c6c;
}

.upload-success {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #67c23a;
}
</style>
